#ifndef Algebra_sgSuperLU_h
#define Algebra_sgSuperLU_h

#include "LinearSolver.h"

SG_NAMESPACE_OPEN

namespace Algebra
{
    /** @addtogroup LinearSolver */
    // @{

    /**
     * @brief Sovle the sparse matrix equation A*x = b based on the SuperLU library.
     *
     * SuperLU is a general purpose library for the direct solution of large, sparse,
     * nonsymmetric systems of linear equations. It uses MPI, OpenMP and CUDA to support
     * various forms of parallelism. It supports both real and complex datatypes, both
     * single and double precision, and 64-bit integer indexing.
     *
     * @see https://portal.nersc.gov/project/sparse/superlu/
     *
     * To hide the underlying implementaion details, GoF's Adapter Pattern has been taken
     * to convert SuperLU's interfaces into our system.
     *
     * @author nene
     * @date July, 2024.
     *
     */
    class ALGEBRA_EXPORT sgSuperLU : public LinearSolver
    {
      public:
        sgSuperLU ();
        ~sgSuperLU () override;

        const char* getClassName () override
        {
            return "sgSuperLU";
        };

        /// perform a numeric factorization of the given sparse matrix.
        void compute (const SpMat_t& matrix) override;

        /// evaluate the solution x of Ax=b using the current decomposition of A.
        Vec_t solve (const Vec_t& b) const override;

        /// report whether previous computation was successful.
        Info_t info () const override;

      private:
        /// reset the solver state
        void init ();
        /// de-allocate the resouces for the factorization.
        void clearFactors ();

      private:
        bool m_factorizationIsOk = false;
        /// take Adapter Pattern to hide the underlying details.
        struct sgSuperLUPrivate* d = nullptr;
    };

    // @}
}  // namespace Algebra

SG_NAMESPACE_CLOSE

#endif  // Algebra_sgSuperLU_h